﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;

namespace BaiduMapShortScrreen
{
    enum MoveDir
    {
        Left = 0,
        Right = 1,
        Top = 2,
        Bottom = 3
    }
    struct WorkInfo
    {
        public string name;
        public int row;
        public int col;
        public int x;
        public int y;
        public Rectangle rect;
    }

    public partial class Form1 : Form
    {
        ChromiumWebBrowser _chromeBrowser;
        //System.Timers.Timer timer;
        Task tasker = null;
        WorkInfo workInfo = new WorkInfo();
        bool working = false;
        bool loading = false;
        bool insertScripted = false;
        bool quitTask = false;

        public Form1()
        {
            InitializeComponent();
            InitializeChromium();
        }

        private void InitializeChromium()
        {
            CefSettings settings = new CefSettings();
            Cef.Initialize(settings);

            _chromeBrowser = new ChromiumWebBrowser(textAddress.Text);
            panelWebBrowser.Controls.Add(_chromeBrowser);
            _chromeBrowser.Dock = DockStyle.Fill;
            _chromeBrowser.LoadingStateChanged += OnLoadingStateChanged;
        }

        private void insterScript()
        {
            if (insertScripted)
            {
                return;
            }

            insertScripted = true;
            //_chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"function hideAll(val){
            //    if (val){
            //        $('#left-panel').hide();//搜索框
            //        $('#tooltip-route').hide();//路线
            //        $('#app-right-top').hide();//右上角
            //        $('#map-operate').hide();//指南针，缩放
            //        $('#mapType-wrapper').hide();//地图类型切换
            //        $('#newuilogo').hide();//logo
            //        $('#MapHolder > div.BMap_scaleCtrl.anchorBL').hide();//比例尺
            //        $('#MapHolder > div.BMap_cpyCtrl.BMap_noprint.anchorBL').hide();//icp相关
            //    }else{
            //        $('#left-panel').show();//搜索框
            //        $('#tooltip-route').show();//路线
            //        $('#app-right-top').show();//右上角
            //        $('#map-operate').show();//指南针，缩放
            //        $('#mapType-wrapper').show();//地图类型切换
            //        $('#newuilogo').show();//logo
            //        $('#MapHolder > div.BMap_scaleCtrl.anchorBL').show();//比例尺
            //        $('#MapHolder > div.BMap_cpyCtrl.BMap_noprint.anchorBL').show();//icp相关
            //        return true;
            //    }
            //    return true;
            //};");

            //_chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"function hideFloors(val){
            //    if (val){
            //        $('.floor-select-container').hide();
            //    }else{
            //        $('.floor-select-container').show();
            //    }
            //    return true;
            //};");

            //_chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"function moveMap(dir, count){
            //        var canvas = $('canvas')[0];
            //        var width = canvas.width;
            //        var height = canvas.height;
            //        switch (dir)
            //        {
            //            case 0:
            //                window.map._setPlatformPosition(width*count, 0);
            //                break;
            //            case 2:
            //                window.map._setPlatformPosition(0, height*count);
            //                break;
            //            case 1:
            //                window.map._setPlatformPosition(-width*count, 0);
            //                break;
            //            case 3:
            //                window.map._setPlatformPosition(0, -height*count);
            //                break;
            //        }
            //    return true;
            //    }");


        //    _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"window.onkeyup=function(k){
        //        var canvas = $('canvas')[0];
        //        var width = canvas.width;
        //        var height = canvas.height;
        //        switch(k.key){
        //            case 'a':
        //            window.map._setPlatformPosition(width, 0);
        //            break;
        //            case 'w':
        //            window.map._setPlatformPosition(0, height);
        //            break;
        //            case 'd':
        //            window.map._setPlatformPosition(-width, 0);
        //            break;
        //            case 's':
        //            window.map._setPlatformPosition(0, -height);
        //            break;
        //        }
        //    return true;
        //    }");
        }


        private void Screenshot(string path, string name)
        {
            Rectangle rect = workInfo.rect;
            Image img = new Bitmap(rect.Width, rect.Height);
            Graphics g = Graphics.FromImage(img);
            g.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size);
            if (!System.IO.Directory.Exists($"./screenshot/{path}"))
            {
                System.IO.Directory.CreateDirectory($"./screenshot/{path}");
            }
            img.Save($"./screenshot/{path}/{name}.png", System.Drawing.Imaging.ImageFormat.Png);
            g.Dispose();
            img.Dispose();
            //截图窗体上任意位置的控件
        }

        private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
        {
            loading = args.IsLoading;
            if (!args.IsLoading)
            {
                insterScript();
            }
        }

        private void textAddress_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                insertScripted = false;
                _chromeBrowser.Load(textAddress.Text);
            }
        }

        private string getTimeStamp()
        {
            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }

        private void setStartButtonText(string name)
        {
            buttonStart.Text = name;
        }

        private void runScript(string text)
        {
            _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(text);
        }


        private void onTimer(object sender, ElapsedEventArgs e)
        {
            if (working == false  && loading == false)
            {
                working = true;
                procTimer();
                working = false;
            }
        }

        private void procTimer()
        {
            Action invokeAction = new Action(procTimer);
            if (this.InvokeRequired)
            {
                //与调用线程不同的线程上创建（说明您必须通过 Invoke 方法对控件进行调用）
                this.Invoke(invokeAction);
            }
            else
            {
                if (workInfo.x < workInfo.row)
                {
                    // 1.拍照
                    Screenshot(workInfo.name, $"{workInfo.y}-{workInfo.x}");
                    runScript($"moveMap({(int)MoveDir.Right}, 1);");
                    labelCurrentRow.Text = workInfo.x.ToString();
                    workInfo.x++;
                    return;
                }
                else
                {
                    workInfo.y++;
                    labelCurrentCol.Text = workInfo.y.ToString();
                    if (workInfo.y < workInfo.col)
                    {
                        workInfo.x = 0;
                        labelCurrentRow.Text = workInfo.x.ToString();
                        runScript($"moveMap({(int)MoveDir.Left}, {workInfo.row});");
                        runScript($"moveMap({(int)MoveDir.Bottom}, 1);");
                    }
                    else
                    {
                        runScript($"moveMap({(int)MoveDir.Left}, {workInfo.row});");
                        runScript($"moveMap({(int)MoveDir.Top}, {workInfo.col-1});");
                        setStartButtonText("开始截图");
                        quitTask = true;
                        tasker = null;
                        MessageBox.Show("完成");
                    }
                }
            }
        }


        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (tasker == null)
            {
                setStartButtonText("停止");
                workInfo.row = int.Parse(textRow.Text);
                workInfo.col = int.Parse(textCol.Text);
                workInfo.name = $"{getTimeStamp()}_{workInfo.row}_{workInfo.col}";
                workInfo.x = 0;
                workInfo.y = 0;

                Point screenPoint = _chromeBrowser.PointToScreen(new Point());
                workInfo.rect = new Rectangle(screenPoint, _chromeBrowser.Size);

                int sleep = int.Parse(textSleep.Text);
                quitTask = false; 
                tasker = Task.Run(() => {
                    while (!quitTask)
                    {
                        if (working == false && loading == false)
                        {
                            working = true;
                            procTimer();
                            working = false;
                        }
                        Thread.Sleep(sleep);
                    }
                });
                //tasker.Start();
            }
            else
            {
                setStartButtonText("开始截图");
                quitTask = true;
                tasker = null;
            }
            return;
        }

        private void buttonDevTools_Click(object sender, EventArgs e)
        {
            _chromeBrowser.ShowDevTools();
        }

        private void checkHideStorey_CheckedChanged(object sender, EventArgs e)
        {
            //if (((CheckBox)sender).Checked)
            //{
            //    _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("hideFloors(true);");
            //}
            //else
            //{
            //    _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("hideFloors(false);");
            //}
        }

        private void checkHideAll_CheckedChanged(object sender, EventArgs e)
        {
            if (((CheckBox)sender).Checked)
            {
                _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("hideOther(true);");
            }
            else
            {
                _chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("hideOther(false);");
            }
        }

        private void buttonMergeImage_Click(object sender, EventArgs e)
        {

            if (workInfo.row == 0)
            {
                FolderBrowserDialog dialog = new FolderBrowserDialog();
                dialog.SelectedPath = Application.StartupPath + "\\screenshot";
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    workInfo.name = dialog.SelectedPath.Substring(dialog.SelectedPath.LastIndexOf('\\'));
                    string[] substrings = workInfo.name.Split('_');
                    workInfo.row = int.Parse(substrings[1]);
                    workInfo.col = int.Parse(substrings[2]);
                    workInfo.rect.Location = new Point(0, 0);
                    Bitmap clip = new Bitmap($"./screenshot/{workInfo.name}/0-0.png");
                    workInfo.rect.Size = clip.Size;
                    clip.Dispose();
                }
                else
                {
                    return;
                }
            }

            int width = workInfo.rect.Size.Width * workInfo.row;
            int height = workInfo.rect.Size.Height * workInfo.col;

            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppRgb555);
            Graphics graphics = Graphics.FromImage(bitmap);
            for (int y = 0; y < workInfo.col; y++)
            {
                for (int x = 0; x < workInfo.row; x++)
                {
                    Bitmap clip = new Bitmap($"./screenshot/{workInfo.name}/{y}-{x}.png");
                    graphics.DrawImage(clip, x * workInfo.rect.Size.Width, y * workInfo.rect.Size.Height);
                    clip.Dispose();
                }
            }
            bitmap.Save($"./screenshot/{workInfo.name}/map.png");
            graphics.Dispose();
            bitmap.Dispose();

            MessageBox.Show("合并完成");
        }

        private void buttonScreenshort_Click(object sender, EventArgs e)
        {
            workInfo.rect.Size = _chromeBrowser.Size;
            Screenshot("./", getTimeStamp());
        }
    }
}
